﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace CSharp10.NetFundamentals
{
    internal class StringAndTextHanding
    {
        public static void Show()
        {
            /*Console.WriteLine(Char.ToUpper('c'));
            Console.WriteLine(Char.IsWhiteSpace('\t'));
            Console.WriteLine(char.ToUpper('i')=='I');
            Console.WriteLine(new string('*',10));
            Console.WriteLine("quick brown fox".EndsWith("fox"));
            Console.WriteLine("quick brown fox".Contains("brown"));
            bool res = "abcdef".StartsWith("aBc", StringComparison.InvariantCultureIgnoreCase);
            Console.WriteLine(res);
            Console.WriteLine("abcde".IndexOf("cd"));
            Console.WriteLine("abcde abcde".IndexOf("CD", 6, StringComparison.CurrentCultureIgnoreCase));
            Console.WriteLine("ab,cd ef".IndexOfAny(new char[] { ' ', ',' }));
            Console.WriteLine("pas5w0rd".IndexOfAny("0123456789".ToCharArray()));
            Console.WriteLine("ab,cd ef".LastIndexOfAny(new char[] { ' ', ',' }));
            Console.WriteLine("pas5w0rd".LastIndexOfAny("0123456789".ToCharArray()));
            string left3 = "12345".Substring(0, 3);
            Console.WriteLine(left3);
            string mid3 = "12345".Substring(1,3);
            Console.WriteLine(mid3);
            string end3 = "12345".Substring(2);
            Console.WriteLine(end3);
            string s1 = "helloworld".Insert(5, ", ");
            Console.WriteLine(s1);
            string s2 =s1.Remove(5,2);
            Console.WriteLine(s2);
            Console.WriteLine("12345".PadLeft(9,'*'));
            Console.WriteLine("12345".PadLeft(9));
            Console.WriteLine("  abcde \t\r\n".Trim().Length);
            string sentence = string.Concat("The", " quick", " brown", " fox");
            string sameSentence = "The" + " quick" + " brown" + " fox";
            Console.WriteLine(sentence);
            Console.WriteLine(sameSentence);
            string composite = "It's {0} degrees in {1} on this {2} moring";
            string s = string.Format(composite, 35, "Perth", DateTime.Now.DayOfWeek);
            Console.WriteLine(s);
            string composite = "Name={0,-20} Credit Limit={1,15:C}";
            Console.WriteLine(string.Format(composite,"Mary",500));
            Console.WriteLine(string.Format(composite,"Elizabeth",20000));
            Console.WriteLine(string.Equals("foo","FOO",StringComparison.CurrentCultureIgnoreCase));
            Console.WriteLine("Boston".CompareTo("Austin"));
            Console.WriteLine("Boston".CompareTo("Boston"));
            Console.WriteLine("Boston".CompareTo("Chicago"));
            Console.WriteLine(string.Compare("foo","FOO",true));
            Console.WriteLine(new TimeSpan(2,30,0));
            Console.WriteLine(TimeSpan.FromHours(2.5));
            Console.WriteLine(TimeSpan.FromHours(-2.5));
            Console.WriteLine(TimeSpan.FromHours(2)+TimeSpan.FromMinutes(20));
            Console.WriteLine(TimeSpan.FromDays(10)-TimeSpan.FromSeconds(1));
            TimeSpan nearlyTenDay = TimeSpan.FromDays(10) - TimeSpan.FromSeconds(1);
            Console.WriteLine(nearlyTenDay.Days);
            Console.WriteLine(nearlyTenDay.Hours);
            Console.WriteLine(nearlyTenDay.Minutes);
            Console.WriteLine(nearlyTenDay.Seconds);
            Console.WriteLine(nearlyTenDay.Milliseconds);
            DateTime d = new DateTime(5767,1,1,new System.Globalization.HebrewCalendar());
            Console.WriteLine(d);
            Console.WriteLine(DateTime.Now);
            Console.WriteLine(DateTimeOffset.Now);
            Console.WriteLine(DateTime.Today);
            Console.WriteLine(DateTime.UtcNow);
            Console.WriteLine(DateTimeOffset.UtcNow);
            DateTime dt = new DateTime(2000, 2, 3, 10, 20, 30);
            Console.WriteLine(dt.Year);
            Console.WriteLine(dt.Month);
            Console.WriteLine(dt.Day);
            Console.WriteLine(dt.DayOfWeek);
            Console.WriteLine(dt.DayOfYear);
            Console.WriteLine(dt.Hour);
            Console.WriteLine(dt.Minute);
            Console.WriteLine(dt.Second);
            Console.WriteLine(dt.Millisecond);
            Console.WriteLine(dt.Ticks);
            Console.WriteLine(dt.TimeOfDay);
            TimeSpan ts = TimeSpan.FromMinutes(90);
            Console.WriteLine(dt.Add(ts));
            Console.WriteLine(dt+ts);
            DateTime thisYear = new DateTime(2015,1,1);
            DateTime nextYear = thisYear.AddYears(1);
            TimeSpan oneYear = nextYear - thisYear;
            Console.WriteLine(oneYear);
            Console.WriteLine(thisYear);
            Console.WriteLine(nextYear);
            DateTime dateTime = DateTime.Now;
            string strDate = dateTime.ToString();
            string strTime = dateTime.ToString("O");
            Console.WriteLine(strDate);
            Console.WriteLine(strTime);
            DateTime dt = DateTime.Parse(strDate);
            Console.WriteLine(dt);

            DateTime dt1 = new DateTime(2000,1,1,10,20,30,DateTimeKind.Local);
            DateTime dt2 = new DateTime(2000,1,1,10,20,30, DateTimeKind.Utc);
            Console.WriteLine(dt1==dt2);
            DateTime local = DateTime.Now;
            DateTime utc = local.ToUniversalTime();
            Console.WriteLine(local==utc);

            DateTimeOffset local = DateTimeOffset.Now;
            DateTimeOffset utc = local.ToUniversalTime();
            Console.WriteLine(local.Offset);
            Console.WriteLine(utc.Offset);
            Console.WriteLine(local == utc);
            Console.WriteLine(local.EqualsExact(utc));
            TimeZone zone = TimeZone.CurrentTimeZone;
            Console.WriteLine(zone.StandardName);
            Console.WriteLine(zone.DaylightName);

            DaylightTime day = zone.GetDaylightChanges(2019);
            Console.WriteLine(day.Start.ToString("M"));
            Console.WriteLine(day.End.ToString("M"));
            Console.WriteLine(day.Delta);
            TimeZoneInfo zone = TimeZoneInfo.Local;
            Console.WriteLine(zone.StandardName);
            Console.WriteLine(zone.DaylightName);

            DateTime dt1 = new DateTime(2019,1,1);
            DateTime dt2 = new DateTime(2019,6,1);
            Console.WriteLine(zone.IsDaylightSavingTime(dt1));
            Console.WriteLine(zone.IsDaylightSavingTime(dt2));
            Console.WriteLine(zone.GetUtcOffset(dt1));
            Console.WriteLine(zone.GetUtcOffset(dt2));*/

            /*TimeZoneInfo wa = TimeZoneInfo.FindSystemTimeZoneById("W.Australia Standard Time");
            Console.WriteLine(wa.Id);
            Console.WriteLine(wa.DisplayName);
            Console.WriteLine(wa.BaseUtcOffset);
            Console.WriteLine(wa.SupportsDaylightSavingTime);

            foreach (TimeZoneInfo zoneInfo in TimeZoneInfo.GetSystemTimeZones())
            {
                Console.WriteLine(zoneInfo.Id);
            }*/

            // .NET 定义了三个 IFormatProvider 类 NumberFormatInfo\DateTimeFormatInfo\CultureInfo 
            /* NumberFormatInfo f = new NumberFormatInfo();
             f.CurrencySymbol = "$$";
             Console.WriteLine(3.ToString("C",f));
             Console.WriteLine(10.3.ToString("C"));
             Console.WriteLine(10.3.ToString("F4"));

             CultureInfo uk = CultureInfo.GetCultureInfo("en-GB");
             Console.WriteLine(2.ToString("C",uk));

             DateTime dt = new DateTime(2000, 1, 2);
             CultureInfo iv = CultureInfo.InvariantCulture;
             Console.WriteLine(dt.ToString(iv));
             Console.WriteLine(dt.ToString("d",iv));

            NumberFormatInfo f = new NumberFormatInfo();
             f.NumberGroupSeparator = " ";
             Console.WriteLine(12345.67890.ToString("N3",f));
            //NumberFormatInfo f =(NumberFormatInfo)CultureInfo.CurrentCulture.NumberFormat.Clone();
              string composite = "Credit={0:C}";
              Console.WriteLine(string.Format(composite,500));
              Console.WriteLine("Credit={0:C}",400);*/


            /*//int error = int.Parse("(2)");
            int minusTo = int.Parse("(2)",NumberStyles.Integer | NumberStyles.AllowParentheses);
            Console.WriteLine(minusTo);
            decimal fivePointTwo = decimal.Parse("5.20", NumberStyles.Currency, CultureInfo.GetCultureInfo("zh-cn"));
            Console.WriteLine(fivePointTwo);*/

            /*  // 以下代码没有运行成功
              double n = -123.456;
              IFormatProvider provider = new WordyFormatProvider();
              Console.WriteLine(string.Format(provider,"{0:C} in words is {0:W}",n));

              int thousand = int.Parse("3E8",NumberStyles.HexNumber);
              Console.WriteLine(thousand);
              int thousand2 = int.Parse("3E8");
              Console.WriteLine(thousand2);

            BigInteger googol = BigInteger.Pow(10, 100);
            Console.WriteLine(googol.ToString());
            double g2 = (double)googol;
            Console.WriteLine(g2);
            BigInteger g3 = (BigInteger)g2;
            Console.WriteLine(g3);
            RandomNumberGenerator rand = RandomNumberGenerator.Create();
            byte[] bytes = new byte[32];
            rand.GetBytes(bytes);
            var bigRandomNumber = new BigInteger(bytes);
            Console.WriteLine(bigRandomNumber);*/

            /* Half h = (Half)123.456;
             Console.WriteLine(h);
             Console.WriteLine(Half.MinValue);
             Console.WriteLine(Half.MaxValue);
             Console.WriteLine((Half)65500);
             Console.WriteLine((Half)65490);
             Console.WriteLine((Half)65480);

            var c1 = new Complex(2, 3.5);
            var c2 = new Complex(3, 0);
            Console.WriteLine(c1.Real);
            Console.WriteLine(c1.Imaginary);
            Console.WriteLine(c1.Phase);
            Console.WriteLine(c1.Magnitude);
            Complex c3 = Complex.FromPolarCoordinates(1.3, 5);
            Console.WriteLine(c1+c2);
            Console.WriteLine(c1*c2);

            Random r1 = new Random(1);
            Random r2 = new Random(1);
            Console.WriteLine(r1.Next(100)+","+r1.Next(100));
            Console.WriteLine(r2.Next(100) + "," + r2.Next(100));

            var rand =  RandomNumberGenerator.Create();
            byte[] bytes = new byte[32];
            rand.GetBytes(bytes);
            Console.WriteLine(rand);*/

            /* Guid guid = Guid.NewGuid();
             Console.WriteLine(guid);
             Guid g = Guid.Empty;
             Console.WriteLine(g);

            var dt1 = new DateTimeOffset(2010, 1, 1, 1, 1,1, TimeSpan.FromHours(8));
            var dt2 = new DateTimeOffset(2010, 1, 1, 1, 1, 1, TimeSpan.FromHours(9));
            Console.WriteLine(dt1==dt2);

            Uri u1 = new Uri("http://www.baidu.com");
            Uri u2 = new Uri("http://www.baidu.com");
            Console.WriteLine(u1==u2);

            var s1 = "http://www.baidu.com";
            var s2 = "http://" + "www.baidu.com";
            Console.WriteLine(s1==s2);*/

            /*  object x = 3, y = 3;
              Console.WriteLine(object.Equals(x, y));
              x = null;
              Console.WriteLine(object.Equals(x, y));
              y = null;
              Console.WriteLine(object.Equals(x, y));

              var tune = new LinkedList<string>();
              tune.AddFirst("do");
              tune.AddLast("so");

              tune.AddAfter(tune.First, "re");
              tune.AddAfter(tune.First.Next, "mi");
              tune.AddBefore(tune.Last, "fa");

              tune.RemoveFirst();
              tune.RemoveLast();

              LinkedListNode<string>? miNode = tune.Find("mi");
              tune.Remove(miNode);
              tune.AddFirst(miNode);
              foreach (var node in tune) Console.WriteLine(node);

            var letters = new HashSet<char>("the quick brown fox");
            Console.WriteLine(letters.Contains('t'));
            Console.WriteLine(letters.Contains('j'));
            //foreach (var item in letters)
            //{
            //    Console.Write(item);
            //}
            //letters.ExceptWith("aeiou");
            letters.SymmetricExceptWith("the lazy brown fox");
            foreach (var item in letters) Console.Write(item);

            var letters = new SortedSet<char>("the quick brown fox");
            foreach (char c in letters) Console.Write(c);
            Console.WriteLine();
            foreach (char c in letters.GetViewBetween('f','i'))
            {
                Console.Write(c);
            }
            var sorted = new SortedList<string, MethodInfo>();
            foreach (var m in typeof(object).GetMethods())
            {
                sorted[m.Name] = m;
            }

            foreach (var m in sorted.Keys)
            {
                Console.WriteLine(m);
            }

            Console.WriteLine();
            foreach (var m in sorted.Values)
            {
                Console.WriteLine(m);
            }

            Console.WriteLine(sorted.Keys[sorted.Count-1]);
            Console.WriteLine(sorted.Values[sorted.Count-1].IsVirtual);*/


            //KeyedCollection
            //Collection<>
            //CollectionBase
            //DictionaryBase


        }
    }

    //public interface IFormattable
    //{
    //    string ToString(string format,IFormatProvider formatProvider);
    //}

    //public interface IFormatProvider
    //{
    //    object GetFormat(Type formatType);
    //}

    public interface ICustomFormatter
    {
        string Format(string format, object arg, IFormatProvider formatProvider);
    }

    public class WordyFormatProvider : IFormatProvider, ICustomFormatter
    {
        static readonly string[] _numberWords = "zero one two three four five six seven eight nine minus point".Split();
        IFormatProvider _parent; // 允许链式编程
        public WordyFormatProvider() : this(CultureInfo.GetCultureInfo("en-US")) { }
        public WordyFormatProvider(IFormatProvider parent)
        {
            _parent = parent;
        }
        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter)) return this;
            return null;
        }

        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            if (arg == null || format != "W")
                return string.Format(_parent, "{0:" + format + "}", arg);

            StringBuilder sb = new StringBuilder();
            string digitList = string.Format(CultureInfo.InvariantCulture, "{0}", arg);
            foreach (char digit in digitList)
            {
                int i = "0123456789-.".IndexOf(digit, StringComparison.InvariantCulture);
                if (i == -1) continue;
                if (sb.Length > 0) sb.Append(' ');
                sb.Append(_numberWords[i]);
            }
            return sb.ToString();
        }
    }

    class Test<T>
    {
        T _value;
        public void SetValue(T newValue)
        {
            if (!object.Equals(newValue, _value))
            {
                _value = newValue;
                OnValueChanged();
            }
        }

        protected virtual void OnValueChanged() { }
    }

    /*    public sealed class LinkedListNode<T>
        {
            public LinkedList<T> List { get; }
            public LinkedListNode<T> Next { get; }

            public LinkedListNode<T> Previous { get; }
            public T Value { get; set; }
        }*/

}
